﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MentalAlchemy.Molecules.MachineLearning
{
	/// <summary>
	/// [molecule]
	/// 
	/// Population size is set by the [parameters.ParentsNumber]
	///   or [parameters.PopulationSize] (ideally they should be the same) and
	///   number of offsprings is defined by the [parameters.OffspringNumber].
	/// </summary>
	[Serializable]
	public class PlusEvolutionStrategy : EvolutionaryAlgorithm
	{
		public override void Init(EAParameters parameters)
		{
			parameters.PopulationSize = parameters.ParentsNumber;
			base.Init(parameters);
		}

		public override void Continue(EAParameters parameters)
		{
			//
			// validate [parameters].
			if (FitnessFunction != null && !EAElements.ValidateParameters(parameters)) throw new Exception("[EvolutionaryAlgorithm.Run]: Invalid parameters setting or fitness function is undefined.");

			Evaluate();
			for (CurrentGeneration = 1; CurrentGeneration <= parameters.GenerationsNumber; ++CurrentGeneration)
			{
				// create children.
				parameters.PopulationSize = parameters.OffspringNumber;
				selPopul = Crossing(popul, parameters);
				
				// mutation.
				Mutation(selPopul, parameters);

				// evaluate children.
				Individual childBest;
				Evaluation(selPopul, FitnessFunction, out childBest);

				// merge two populations and perform selection.
				popul.AddRange(selPopul);
				popul = EAElements.TruncationSelection(popul, parameters.PopulationSize);

				// save the best.
				bestInd = (Individual)popul[0].Clone();
			}

			Evaluate();	// final population evaluation.
		}
	}
}
